///////////////////////////////////////////////////////////////////////////////////////////////////
// Illusion Ray Development Kit (IDK)           Copyright (c) 2010 ( dimitriy.martynenko@gmail.com )
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2010-05-22
// Updated : ...
// Licence : NEW BSD
// Info	   : "SCL" Safe Code Lib (for C++ unmanaged)
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

namespace Platform
{
    namespace Symbian
    {
#       include <e32def.h> /* Symbian OS defines */
//#     include <e32debug.h> /* Symbian OS defines */
//#     include <e32math.h>
#       include <time.h>
#       include <unistd.h>
#       include <stdio.h>
    }

    inline float Time::Get(void)
    {
        return Symbian::clock();
    }

    inline void Time::Sleep(uint ms)
    {
        Symbian::sleep(ms);
    }

    //
    // OutputConsole Win32 Impl
    //
    inline void OutputConsole::Message(const char* text)
    {
        //RDebug::Print();
    }

    //
    // FileHandle
    //
    class FileHandle
    {
    private:
            FileHandle(const FileHandle&);
            FileHandle& operator=(const FileHandle&);
    private:
            Symbian::FILE* mHandle;
    public:
            FileHandle() : mHandle(NULL)
            {
            }

            bool IsValid() const
            {
                mHandle != NULL;
            }

            bool Open(const char* path, bool create)
            {
                mHandle = Symbian::fopen(path, "r");
            }

            void Close()
            {
                Symbian::fclose(mHandle);
            }

            uint GetSize() const
            {
                uint pos = Symbian::ftell(mHandle);
                Symbian::fseek(mHandle, 0, SEEK_END);
                uint end = Symbian::ftell(mHandle);
                Symbian::fseek(mHandle, pos, SEEK_SET);

                return end;
            }

            void SetPosition(uint pos)
            {
                fseek(mHandle, pos, SEEK_SET);
            }

            void Seek(uint pos)
            {
                fseek(mHandle, pos, SEEK_CUR);
            }

            template<typename T>
            bool Read(T data, uint size, dword& bread)
            {
                bread = fread(data, size, 1,mHandle);
                return bread == size;
            }
    };

    //
    // TRefCounter Win32 Impl
    //
    //NOTE : Win32 will be use Interlocked...Acquire when perfomance is critical?

    template<>
    inline void TRefCounter<Config::ThreadSafe>::AddRef(void)
    {
    }

    template<>
    inline bool TRefCounter<Config::ThreadSafe>::Release()
    {
    }

    //
    // TThreadLocker Win32 Impl
    //
    class Locker
    {
    private:
            Locker(const Locker&);
            Locker& operator=(const Locker&);
    private:
            volatile long mThreadID;
    public:
            inline Locker() : mThreadID(0) {}

            volatile inline bool TryLock(void)
            {
            }

            volatile inline void UnLock(void)
            {
            }
    };

    //
    // TMutex Win32 Impl
    //
    template<>
    class TMutex<Config::ThreadSafe>
    {
    private:
            Locker& mLocker;
    private:
            TMutex(const TMutex&);
            TMutex& operator=(const TMutex&);
    private:
            inline void Enter()
            {
            }

            inline void Leave()
            {
            }
    public:
            inline TMutex(Locker& locker) : mLocker(locker)
            {
                    Enter();
            }

            ~TMutex()
            {
                    Leave();
            }
    };

    //
    // Event Win32 Impl
    //
    class Event
    {
    public:
    private:
            Event(const Event&);
            Event& operator=(const Event&);
    public:
            Event(bool autoReset)
            {
            }

            ~Event()
            {
            }

            void Set()
            {
            }

            void Reset()
            {
            }
    };

    //
    // TEventCondition Win32 Impl
    //

    class EventCondition
    {
    private:
            EventCondition(const EventCondition&);
            EventCondition& operator=(const EventCondition&);
    public:
            typedef unsigned int EventID;

            EventCondition(){}

            bool Wait(Event& event1)
            {

            }

            EventID Wait(Event& event1, Event& event2)
            {
            }
    };

    //
    // Thread Win32 Impl
    //

    class ThreadHandle
    {
    private:
            ThreadHandle(const ThreadHandle&);
            ThreadHandle& operator=(const ThreadHandle&);
    private:
    private:
            //template<typename Derived, void (Derived::*action)()>
            //static Win32::DWORD WINAPI __ThreadCall(void* p)
            //{
            //}
    public:
            ThreadHandle(){}

            template<typename Derived, void (Derived::*action)()>
            void Create(Derived* caller)
            {
            }

            void Close()
            {
            }
    };


    template<typename T>
    inline T Math<T>::Sqrt(T x)
    {
    }

    template<typename T>
    inline T Math<T>::Sin(T x)
    {
    }

    template<typename T>
    inline T Math<T>::Cos(T x)
    {
    }

    template<typename T>
    inline T Math<T>::ArcTan2(T y, T x)
    {
    }
}
